package cn.xiaopengstack.types.framework.strategy.tree;

import lombok.Getter;
import lombok.Setter;

import java.util.Objects;

/**
 * @author jiangyangang
 * 策略抽象类
 */
public abstract class AbstractStrategyRouter<T, D, R> implements StrategyHandler<T, D, R>, StrategyMapping<T, D, R>{
    /**
     * 获取策略
     */
    @Getter
    @Setter
    protected StrategyHandler<T, D, R> defaultStrategyHandler = StrategyHandler.DEFAULT;

    /**
     * 执行路由
     * @param param
     * @param dynamicContext
     * @return
     * @throws Exception
     */
    public R route(T param, D dynamicContext) throws  Exception {
        StrategyHandler<T, D, R> strategyHandler = get(param, dynamicContext);
        if (Objects.nonNull(strategyHandler)) {
            return strategyHandler.apply(param, dynamicContext);
        }

        return defaultStrategyHandler.apply(param, dynamicContext);
    }

    @Override
    public R apply(T requestParameter, D dynamicContext) throws Exception {
        // 加载数据
        multiLoadData(requestParameter, dynamicContext);
        // 执行策略
        return doApply(requestParameter, dynamicContext);
    }

    /**
     * 并行加载策略节点需要的数据
     * @param param
     * @param dynamicContext
     * @throws Exception
     */
    protected abstract void multiLoadData(T param, D dynamicContext) throws Exception;

    /**
     * 受理业务流程
     * @param param
     * @param dynamicContext
     * @return
     * @throws Exception
     */
    protected abstract R doApply(T param, D dynamicContext) throws Exception;
}
